Android root相关调研


需求

老大给的需求
1,sdk/apk拦截手机短信,并且清除手机系统短信收件箱该条短信记录。
2,安装apk,最好是静默安装

需求分析

短信拦截

首先手机短信的拦截应该是很好实现的,目前竞品中有很多已经实现了该功能的产品,如360手机卫士等。
因为短信广播是系统级别的广播,只需在Manifest.xml里加”接收”SMS的权限,再注册一个receiver便可以监听到短信的收发,至于拦截部分,可以通过ContentObserver进行拦截监听。
在4.4前,短信拦截都是通过动态注册高优先级BroadcastReceiver的方式进行拦截的,主要是用于跟竞品进行短信抢占。而现在ContenetObserver是并行通知的情况下,如果过滤逻辑不够快,依然有可能会被竞品抢先把短信先删除掉,导致拿到的最后一次短信是旧的短信。建议结合BroadcastReceiver和ContenetObserver进行拦截,BroadcastReceiver做内容校正和后备数据,以防拿到的最后一条短信是旧的时候,依然可以进行正常的拦截流程。

相关资料代码有

1
http://www.cnblogs.com/gaojunfeng/articles/3155283.html
1
http://www.javaapk.com/tools/safety/389.html
1
http://www.javaapk.com/tools/safety/4627.html

apk安装

要是说静默安装,那只能root了,这个难度比较大,所以做了些系统的调研工作。
首先现在主流的root竞品应用
1,kingroot
2,pingpongroot
3,360超级root
4,一键root大师
5,百度一键root
6,超级root大师
7,root精灵
8,root助手

何谓root

Android系统默认的su程序只能root和shell可以用运行su。
不光root手机上su需要设置SUID,所有的Linux系统上的su程序都需要设置SUID位。
这样我们就可以看出其实Android系统的破解的根本原理就是替换掉系统中的su程序,因为系统中的默认su程序需要验证实际用户权限(只有root和shell用户才有权运行系统默认的su程序,其他用户运行都会返回错误)。而破解后的su将不检查实际用户权限,这样普通的用户也将可以运行su程序, 也可以通过su程序将自己的权限提升,然后利用superuser.apk将已提权的系统进行管理。
所以root得本质都是将su文件复制到Android系统/system/xbin目录下,将所有者更换成root用户,并用chmod命令设置为可执行权限和setuid(s)权限。

所以现在的root软件都是做了上面的工作,首先得解决提权的问题,所以千千万万的挖洞工作就开始了。
已经利用的漏洞整理.

序号 漏洞类型/名称 针对版本及描述
1 Exploid Up to Android 2.1 Eclair
2 ASHMEM Up to Android 2.2 Froyo
3 ZimperLich Up to Android 2.2 Froyo
4 Gingerbreak Up to Android 2.3.2 Gingerbread
5 Levitator Up to Android 2.3.5 Gingerbread; devices with PowerVR SGX
6 ZergRush Up to Android 2.3.* Gingerbread; patched in different GB versions by different vendors
7 Mempodroid Up to Android 4.0.4 ICS
8 Wunderbar Linux kernel exploit; may or may not be patched yet

又google到相关机型的特定root提权漏洞

Vulnerability/Exploit name author effect (root, unlock,…) link
psneuter scotty2 root https://github.com/tmzt/g2root-kmod/blob/master/scotty2/psneuter/psneuter.c
Exploid Stealth root http://c-skills.blogspot.com/2010/07/android-trickery.html
GingerBreak Stealth root http://c-skills.blogspot.com/2011/04/yummy-yummy-gingerbreak.html
RageAgainstTheCage Stealth root
KillingInTheNameOf Stealth root http://c-skills.blogspot.com/2011/01/adb-trickery-again.html
Zimperlich Stealth http://c-skills.blogspot.com/2011/02/zimperlich-sources.html
Zergrush Revolutionary root https://github.com/revolutionary/zergRush/blob/master/zergRush.c
Tacoroot jcase root https://github.com/CunningLogic/TacoRoot
Nachoroot jcase root https://github.com/CunningLogic/NachoRoot
Burritoroot jcase root https://github.com/CunningLogic/BurritoRoot
Gorditaroot jcase install custom recovery or root https://github.com/CunningLogic/GorditaRoot
Enchilada jcase install custom recovery or root https://github.com/CunningLogic/GorditaRoot

等等等

挖洞难,利用这些洞绕过系统内核的安全机制更不容易,并且android内核碎片化严重,通用的洞几乎找不到,所以亦是比较佩服这些专做root的团队精英。
Google Code上找到了zerbrush老版本的源码,经测试4.1以前的android版本都可以root(测试的不够充分)。

1
https://github.com/huanxingxyz/z4root/tree/master/z4root-read-only

总之,root设备难度比较大,因为android的碎片化太严重了,想找通用洞肯定是不可能的,大部分root应用都应该有自己维护的一套机型root漏洞库,通过获取设备型号匹配相应的root方案,进行root,所以root核心方案肯定不只一套,并且5.0以上的系统几乎很少有root应用进行提权,因为内核漏洞补丁也在持续更新修复,以上版本的root会更加困难。

插件化

相对于root,插件化方案看上去更加可行。

插件化解决的问题

1,减小主包大小
2,不发版上新功能
3,独立开发加载 A/B TEST 模块
4,bug 修复工具
首先插件化和热修复能不使用就不使用,本身这种做法是 Google 不推荐的,RN才是今后的发展方向。
apk 分为宿主和插件部分,插件在需要的时候才加载进来。

实现插件化需要解决的技术点

1,资源如何加载(资源冲突问题如何解决)?
2,代码如何加载访问访问?
3,插件的管理后台包括的内容?
4,插件的增量更新问题(非必须)
5,加载插件中的so库 (非必须)

相关开源

框架名称 出现时间 作者 实现简介 已知存在问题
AndroidDynamicLoader 2012年7月 mmin18 不使用Activity采用Fragment实现
DynamicAPK 携程 扩展aapt解决资源问题
android-pluginmg houkx 动态创建Activity来实现插件化
DynamicLoadApk 2014年底 百度工程师 任玉刚 通过代理Activity来实现插件化
DroidPlugin 2015年8月 奇虎360 深度hook实现 不支持通知栏定制
Small 2015年底 林光亮 比较DroidPlugin轻量一点,脚本来解决资源问题 不支持Service插件化
ACCD 2015年4月 bunnyblue OpenAtlas 之后改为ACCD 携程开源框架参考了这个
xcombine https://www.oschina.net/p/xcombine

详细

目前插件包有两种格式:一种是apk,一种是dex包.对插件的接入机制来说也有两种:一种是需要安装,一种是不需要安装.结合插件包的格式来说插件的方式只有三种:1,apk安装,2,apk不安装,3,dex包.三种方式其实主要是解决两个方面的问题:1,加载插件中的类,2,加载插件中的资源.第一个加载类的问题,这三个方式都可以很好的解决.但目前三种方式都没有很完美的解决第2个问题.

1,apk安装方式.插件apk安装后,可以在主程序中通过包名加载到插件的context,有了插件的context就可以解决加载插件资源的问题.但出现的新问题是:如果插件a,b,c间公用一个底层jar包,那么在abc间传送数据时,需要进行序列化和反序列化,因为a中jar包的data类与b中jar包的data类虽然都是同样的jar包也是同样的类,但两个类在java机制来是由不同的classloader加载的,是不同的类.那么就会出现插件间jar包冗余和数据传递的效率不好问题.总之能解决问题.

2,apk不安装,这个是不推荐的方式.可以通过dexclassloader加载到插件a中的类,但插件没有安装就无法获得插件apk的context,也就无法加载到资源,网络上有牛人通过将主程序的context替换关键的对象(如classloader,assertmanager等),伪造成插件的context,然后通过伪context也可以获得插件资源.目前个人验证的问题为:获取到的layout资源中的textview显示文本有问题,无法显示在layout设定的文本.同时个人猜测这种hack的方式或许有其它的未知的问题,但不排除高手已经解决了这个问题.

3,dex包,这个基本是java开发中jar包的方式.同样通过dexclassloader加载到插件中的类,但依旧没有context,也无法加载到资源.要使用布局,只能在插件中使用java代码来写布局.这种方式最简单(1,类似jar包的方式,也可以随意导出单个类的jar包然后转化为dex包,不存在打包成apk需要完整的工程和依赖关系的要求.2,底层的公用jar包所有插件可以公共一个,传递数据不用反复的序列化和反序列化.),也是最复杂的(布局文件全部代码写,难调试,难维护).

优缺点

插件式开发通俗的讲就是把一个很大的app分成n多个比较小的app,其中有一个app是主app。基本上可以理解为让一个apk不安装也可以被运行。只不过这个运行是有很多限制的运行,所以才叫插件否则就叫病毒了。其实在目前淘宝、百度、腾讯、等都有成熟的动态加载框架,包括apkplug,但是它们都是不开源的。

优点:
1.模块解耦
2.解除单个dex函数不能超过 65535的限制
3.动态升级
4.高效开发(编译速度更快)

基于插件的开发列举两个比较突出的优点:
1、应用程序非常容易扩展,比如一个新的领域要加到旧的应用程序中,只需把这个新的领域做为一个插件,只开发这个小的app就可以了,旧的应用程序可能会原分不动,就连编译打包都不需要。
2、下载更新特别省流量,假如一个应用程序有10M把它分成两个的话可能每次更新只需要花费5M或者更少的流量就可以更新完。

追求完美本来就是一种性格缺陷,说在做软件方面没有近乎完美。基于插件开发当然不是插件越多越好能掌控好内聚和耦合度就更好了。插件增加了主应用程序中的逻辑难度。有优点的东西也是有缺点的这是必然。

缺点:
1.增加了主应用程序的逻辑难度
2.技术有难度,目前一些成熟的框架都是闭源的

参考资料

1.android插件化及动态部署 - ATLAS–伯奎(阿里无线事业部无线技术专家)

1
http://club.alibabatech.org/resource_detail.htm?topicId=84
1
http://v.youku.com/v_show/id_XNTMzMjYzMzM2.html

2.怎么将 Android 程序做成插件化的形式?

1
http://www.zhihu.com/question/19981105/answer/30865268

3.Android 插件化 动态升级

1
http://www.trinea.cn/android/android-plugin/

4.apkplug框架

1
http://www.apkplug.com/

5.Android插件化开发,初入殿堂

1
http://my.oschina.net/kymjs/blog/327232

6.Android 插件框架 AtlasForAndroid(阿里使用框架)

1
https://github.com/bunnyblue/OpenAtlas

Simple Project

1
https://github.com/bunnyblue/OpenAtlasExtension

总结

插件化,热更新也是近期才火的黑科技,确实可以解决一些实质性的问题,比如也可以适当的实现前面说的免安装apk,但是也会有一定的局限性。
总之,功能需要继续调研.
360的插件化开源框架。

1
https://github.com/Qihoo360/DroidPlugin